#include "mp3.h"
#include "media_timer_v2.h"
#include "audio_card.h"
#include "audio_decode.h"
#include "my_malloc.h"
#include "libc.h"
#include "drawtxt.h"
#include "key.h"
#include "mainmenue.h"
#include "sound_kard.h"

#include <math.h>

//#define SINE_WAVE_SIZE 512  // 正弦波数据点数
//#define SAMPLING_FREQ 10000 // 采样频率10kHz
//#define SINE_WAVE_FREQ 5000 // 正弦波频率5kHz

//uint16_t sine_wave[SINE_WAVE_SIZE];
//#ifndef M_PI
//#define M_PI 3.14159265358979323846
//#endif



void GPIO_Configuration(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA, GPIO_Pin_4); // PA.4 输出高
}

void DAC_Configuration(void) {
    DAC_InitTypeDef DAC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

    DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
    DAC_Init(DAC_Channel_1, &DAC_InitStructure);

    DAC_Cmd(DAC_Channel_1, ENABLE);
    DAC_SetChannel1Data(DAC_Align_12b_R, 0); // 12位右对齐数据格式设置DAC值
    
    DAC_DMACmd(DAC_Channel_1, ENABLE);
}
void TIM6_Configuration(int freq) {
    //freq = freq /2;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

    TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock / 2 / freq) - 1; // 计算定时器周期
    TIM_TimeBaseStructure.TIM_Prescaler = 0; // 预分频器
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

    TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
    TIM_Cmd(TIM6, ENABLE);
}

DMA_InitTypeDef DMA_InitStructure;


void dma_dac_irc_init(){
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn; // DMA1通道4中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
    NVIC_Init(&NVIC_InitStructure);
    
    DMA_ITConfig(DMA2_Channel3, DMA_IT_TC, ENABLE);
}


//char sine_wave_flag = 1;
//void my_dma_enable(){
//    static int num = 0;
//    static char flag = 0;
//    if(num > 50){
//        num = 0;
//        flag++;
//        if(sine_wave_flag == 1){
//            for(int i = 0; i < 512;i++){
//                sine_wave1[i] = sine_wave[i] >>1  ;
//            }
//        }else{
//            for(int i = 0; i < 512;i++){
//                sine_wave2[i] = sine_wave[i]>>2  ;
//            }
//        }
//    }else{
//        num++;
//    }
//    if(flag > 5){
//        flag = 0;
//        //generate_sine_wave();
//    }
//    
//    DMA_Cmd(DMA2_Channel3, DISABLE);
//    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &DAC->DHR12R1;
//    //DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sine_wave;
//    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
//    DMA_InitStructure.DMA_BufferSize = SINE_WAVE_SIZE;
//    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular
//    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
//    DMA_Init(DMA2_Channel3, &DMA_InitStructure);

//    DMA_Cmd(DMA2_Channel3, ENABLE);
//    if(sine_wave_flag == 1){
//        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sine_wave1;
//        sine_wave_flag = 2;
//    }else{
//       DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sine_wave2;
//        sine_wave_flag = 1;
//    }
//    
//    //DMA_Init(DMA2_Channel3, &DMA_InitStructure);
//    //DMA_SetCurrDataCounter(DMA2_Channel3,SINE_WAVE_SIZE);
//    DMA_Cmd(DMA2_Channel3, ENABLE);
//}




typedef void feeding_func(void);
#define SOUND_KARD_DATA_FLAG_NUM 2
typedef struct sound_kard{
    int volume;
    int sample_freq;
    int channels;
    int sample_bits;
    int pcm_pkg_size;
    int pcm_data_num;
    uint16_t *pcm_data_1;
    uint16_t *pcm_data_2;
    
    int send_data_flag;
    char data_flag[SOUND_KARD_DATA_FLAG_NUM];
    
    feeding_func * feeding_fun;

}sound_kard_t;

sound_kard_t my_sound_kard;

void DMA_Configuration(void) {
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &DAC->DHR12R1;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)my_sound_kard.pcm_data_1;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = my_sound_kard.pcm_data_num;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA2_Channel3, &DMA_InitStructure);

    DMA_SetCurrDataCounter(DMA2_Channel3,my_sound_kard.pcm_data_num);
    DMA_Cmd(DMA2_Channel3, ENABLE);
    
    DAC_DMACmd(DAC_Channel_1, ENABLE);

    //DAC_DMACmd(DAC_Channel_1, ENABLE);
}
void DMA_Configuration2(void) {
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &DAC->DHR12R1;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)my_sound_kard.pcm_data_1;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = my_sound_kard.pcm_data_num;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA2_Channel3, &DMA_InitStructure);

    //DMA_SetCurrDataCounter(DMA2_Channel3,my_sound_kard.pcm_data_num);
    //DMA_Cmd(DMA2_Channel3, ENABLE);
    
    //DAC_DMACmd(DAC_Channel_1, ENABLE);

    //DAC_DMACmd(DAC_Channel_1, ENABLE);
}
void dma_adc_send_data(){
    DMA_Cmd(DMA2_Channel3, DISABLE);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &DAC->DHR12R1;
    //DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)sine_wave;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = my_sound_kard.pcm_data_num;//SINE_WAVE_SIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    
    if(my_sound_kard.send_data_flag == 1){
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)my_sound_kard.pcm_data_1;
        my_sound_kard.send_data_flag = 2;
    }else{
       DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)my_sound_kard.pcm_data_2;
        my_sound_kard.send_data_flag = 1;
    }
    DMA_Init(DMA2_Channel3, &DMA_InitStructure);
    
    DMA_SetCurrDataCounter(DMA2_Channel3,my_sound_kard.pcm_data_num);
    DMA_Cmd(DMA2_Channel3, ENABLE);

}

void DMA2_Channel3_IRQHandler(void)
{
    if (DMA_GetITStatus(DMA2_IT_TC3) != RESET)
    {
        // 清除中断标志位
        DMA_ClearITPendingBit(DMA2_IT_TC3);
        // 传输完成的其他操作
        //my_dma_enable();
        dma_adc_send_data();
        my_sound_kard.feeding_fun();
    }
}
int audio_card_init(int volume){
    my_sound_kard.volume = volume;
    my_sound_kard.pcm_data_1 = NULL;
    my_sound_kard.pcm_data_2 = NULL;
    my_sound_kard.send_data_flag = 1;
    for(int i = 0; i < SOUND_KARD_DATA_FLAG_NUM; i++){
        my_sound_kard.data_flag[i] = 0;
    }
    
    return 0;
}
void pcm_data_copy(uint16_t *ad_data,int16_t *pcm_data,int pkg_size){
    if(my_sound_kard.channels == 2){
        my_sound_kard.pcm_data_num =  pkg_size /2;
        //pkg_size = pkg_size /2;
        for(int i = 0; i < my_sound_kard.pcm_data_num;i++ ){
            ad_data[i] = ((pcm_data[i] + 32768) >> 4) >> 3;
        }
    }else{
        my_sound_kard.pcm_data_num =  pkg_size   ;
        for(int i = 0; i < my_sound_kard.pcm_data_num;i++ ){
            ad_data[i] = ((pcm_data[i] + 32768) >> 4) >> 3;
        }
    }
}
int audio_card_open(int sample_freq, int channels, int sample_bits, void *pkg_buff, int pkg_size){
    my_sound_kard.sample_freq  = sample_freq;
    my_sound_kard.channels = channels;
    my_sound_kard.sample_bits = sample_bits;
    my_sound_kard.pcm_pkg_size = pkg_size;
    
    audio_card_init(my_sound_kard.volume);
    if(my_sound_kard.channels == 2){
        if(my_sound_kard.pcm_data_1 == NULL){
            my_sound_kard.pcm_data_1 = mem_malloc((pkg_size));
            if(my_sound_kard.pcm_data_1 == NULL) {
                return -1;
            }
        }
        if(my_sound_kard.pcm_data_2 == NULL){
            my_sound_kard.pcm_data_2 = mem_malloc((pkg_size));
            if(my_sound_kard.pcm_data_2 == NULL) {
                mem_free(my_sound_kard.pcm_data_1);
                return -2;
            }
        }
    }else{
        if(my_sound_kard.pcm_data_1 == NULL){
            my_sound_kard.pcm_data_1 = mem_malloc((pkg_size*2));
            if(my_sound_kard.pcm_data_1 == NULL) {
                return -1;
            }
        }
        if(my_sound_kard.pcm_data_2 == NULL){
            my_sound_kard.pcm_data_2 = mem_malloc((pkg_size*2));
            if(my_sound_kard.pcm_data_2 == NULL) {
                mem_free(my_sound_kard.pcm_data_1);
                return -2;
            }
        }
    }
    
    //GPIO_Configuration(); // 初始化GPIO
    //DAC_Configuration(); // 初始化DAC
    TIM6_Configuration(my_sound_kard.sample_freq ); // 初始化定时器6
    //DMA_Configuration(); // 初始化DMA
    
    
    
//    int16_t *pcm_data = pkg_buff;
//    if(my_sound_kard.channels == 2){
//        my_sound_kard.pcm_data_num =  pkg_size /2;
//        //pkg_size = pkg_size /2;
//        for(int i = 0; i < my_sound_kard.pcm_data_num;i++ ){
//            my_sound_kard.pcm_data_1[i] = (pcm_data[i] + 32768) >> 4;;
//        }
//    }else{
//        my_sound_kard.pcm_data_num =  pkg_size ;
//        for(int i = 0; i < my_sound_kard.pcm_data_num;i++ ){
//            my_sound_kard.pcm_data_1[i] = (pcm_data[i] + 32768) >> 4;
//        }
//    }
    pcm_data_copy(my_sound_kard.pcm_data_1,pkg_buff, pkg_size);
    my_sound_kard.data_flag[0] = 1;
    
    
    GPIO_Configuration( );
    DAC_Configuration(); // 初始化DAC
    //TIM6_Configuration(my_sound_kard.sample_freq );
    //DMA_Configuration() ;
    //dma_dac_irc_init();
    
    DMA_Configuration();
    dma_dac_irc_init();
    //dma_adc_send_data();
    my_sound_kard.data_flag[0] = 0;
    my_sound_kard.feeding_fun();
    return 0;
}
int audio_card_get_freq(void){
    return my_sound_kard.sample_freq;
}
int audio_card_get_channels(void){
    return my_sound_kard.channels;
}
int audio_card_chg_freq(int sample_freq){return 0;}
int audio_card_chg_volume(int volume){return 0;}
int audio_card_get_volume(void){
    return my_sound_kard.volume;
}
int audio_card_register_feeder(void (*feeding_func)(void)){
    my_sound_kard.feeding_fun = feeding_func;
    return 0;
}
int audio_card_write(void *pkg_buff, int pkg_size){
    uint16_t *pcm = NULL;
    if(my_sound_kard.send_data_flag == 1){
        pcm = my_sound_kard.pcm_data_1;
    }else{
        pcm = my_sound_kard.pcm_data_2;
    }
    
//    int16_t *pcm_data = pkg_buff;
//    if(my_sound_kard.channels == 2){
//        my_sound_kard.pcm_data_num =  pkg_size /2;
//        //pkg_size = pkg_size /2;
//        for(int i = 0; i < my_sound_kard.pcm_data_num;i++ ){
//            pcm[i] = (pcm_data[i] + 32768) >> 4;;
//        }
//    }else{
//        my_sound_kard.pcm_data_num =  pkg_size ;
//        for(int i = 0; i < my_sound_kard.pcm_data_num;i++ ){
//            pcm[i] = (pcm_data[i] + 32768) >> 4;
//        }
//    }
    pcm_data_copy(pcm,pkg_buff, pkg_size);
    return 0;
}
int audio_card_close(void){
    if(my_sound_kard.pcm_data_2 != NULL) {
        mem_free(my_sound_kard.pcm_data_2);
        //return -2;
    }
    if(my_sound_kard.pcm_data_1 != NULL) {
        mem_free(my_sound_kard.pcm_data_1);
        //return -2;
    }
    my_sound_kard.pcm_data_1 = NULL;
    my_sound_kard.pcm_data_2 = NULL;
    
    DAC_DMACmd(DAC_Channel_1, DISABLE);
    TIM_Cmd(TIM6, DISABLE);
    DAC_Cmd(DAC_Channel_1, DISABLE);
    
    
    DAC_DMACmd(DAC_Channel_1, DISABLE);
    return 0;
}

void audio_card_pause(void){}
void audio_card_resume(void){}
    
    
void test_audio_kard(){

}

#if 0

void GPIO_Configuration(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void DAC_Configuration(void) {
    DAC_InitTypeDef DAC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

    DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
    DAC_Init(DAC_Channel_1, &DAC_InitStructure);

    DAC_Cmd(DAC_Channel_1, ENABLE);
}
void TIM2_Configuration(void) {
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_TimeBaseStructure.TIM_Period = 0xFFF; // 定时器周期
    TIM_TimeBaseStructure.TIM_Prescaler = 0; // 预分频器
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
    TIM_Cmd(TIM2, ENABLE);
}

void DMA_Configuration(void) {
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &DAC->DHR12R1;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)data_buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = sizeof(data_buffer) / sizeof(uint16_t);
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);

    DMA_Cmd(DMA1_Channel3, ENABLE);

    DAC_DMACmd(DAC_Channel_1, ENABLE);
}

int main(void) {
    uint16_t data_buffer[10] = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000};

    GPIO_Configuration();
    DAC_Configuration();
    TIM2_Configuration();
    DMA_Configuration();

    while (1) {
        // 可以在这里添加其他代码
    }
}


void dac_init(){
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能PORTA时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;             // 端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;         // 模拟输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA, GPIO_Pin_4); // PA.4 输出高
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); // 使能DAC通道时钟
    
    DAC_InitTypeDef DAC_InitStructure;
    DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;       // 不使用触发功能
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; // 不使用波形发生
    DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; // 屏蔽、幅值设置
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; // DAC1输出缓存关闭
    DAC_Init(DAC_Channel_1, &DAC_InitStructure); // 初始化DAC通道1
    
    DAC_Cmd(DAC_Channel_1, ENABLE); // 使能DAC1
    
    DAC_SetChannel1Data(DAC_Align_12b_R, 0); // 12位右对齐数据格式设置DAC值
}
void Dac1_Set_Vol(uint16_t vol)
{
    float temp = vol;
    temp /= 1000;
    temp = temp * 4096 / 3.3;
    DAC_SetChannel1Data(DAC_Align_12b_R, (uint16_t)temp); // 12位右对齐数据格式设置DAC值
}


void dam_dac_init(char *data_buffer){
    // 初始化DAC
    DAC_InitTypeDef DAC_InitStructure;
    DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; // 不使用触发功能
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; // 不使用波形发生
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; // 使能输出缓冲
    DAC_Init(DAC_Channel_1, &DAC_InitStructure);

    // 配置DMA
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R1;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)data_buffer; // data_buffer是存储DAC数据的数组
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = sizeof(data_buffer) / sizeof(uint16_t);
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);

    // 使能DMA
    DMA_Cmd(DMA1_Channel3, ENABLE);

    // 启动DAC
    DAC_Cmd(DAC_Channel_1, ENABLE);

    // 启动DMA到DAC的传输
    DAC_DMACmd(DAC_Channel_1, ENABLE);
}


#endif









